home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / Crypt / CBC.php next >
PHP Script  |  2004-03-24  |  9KB  |  333 lines

  1. <?php
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | PHP version 4.0                                                      |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2003 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license,      |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Colin Viebrock <colin@easydns.com>                          |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id: CBC.php,v 1.5 2003/03/13 20:52:38 cmv Exp $
  20. //
  21.  
  22. require_once 'PEAR.php';
  23.  
  24.  
  25. /**
  26.  * Class to emulate Perl's Crypt::CBC module
  27.  *
  28.  * Blowfish support that is compatable with Perl requires libmcrypt >= 2.4.9.
  29.  * If you are using libmcrypt <= 2.4.8, Blowfish encryption will work,
  30.  * but your data will not be readable by Perl scripts.  It will work
  31.  * "internally" .. i.e. this class will be able to encode/decode the data.
  32.  *
  33.  * Blowfish support that is compatable with PHP applications using
  34.  * libmcrypt <= 2.4.8 requies you to use 'BLOWFISH-COMPAT' when
  35.  * specifying the cipher.  Check the libmcrypt docs when in doubt.
  36.  *
  37.  * This class no longer works with libmcrypt 2.2.x versions.
  38.  *
  39.  * NOTE: the cipher names in this class may change depending on how
  40.  * the author of libcrypt decides to name things internally.
  41.  *
  42.  *
  43.  * @version  $Revision: 1.5 $
  44.  * @author   Colin Viebrock <colin@easydns.com>
  45.  * @access   public
  46.  * @package  Crypt
  47.  */
  48.  
  49. class Crypt_CBC extends PEAR {
  50.  
  51.     /**
  52.     * supported procedures
  53.     * @var array
  54.     */
  55.     var $known_ciphers = array (
  56.         'DES'               => MCRYPT_DES,
  57.         'BLOWFISH'          => MCRYPT_BLOWFISH,
  58.         'BLOWFISH-COMPAT'   => MCRYPT_BLOWFISH_COMPAT,
  59.     );
  60.  
  61.     /**
  62.     * used cipher
  63.     * @var string
  64.     */
  65.     var $cipher;
  66.  
  67.     /**
  68.     * crypt resource, for 2.4.x
  69.     * @var string
  70.     */  
  71.     var $TD;
  72.  
  73.     /**
  74.     * crypt deinit function, for backwards compatability
  75.     * @var string
  76.     */  
  77.     var $deinit_function;
  78.  
  79.     /**
  80.     * blocksize of cipher
  81.     * @var string
  82.     */    
  83.     var $blocksize;
  84.  
  85.     /**
  86.     * keysize of cipher
  87.     * @var int
  88.     */    
  89.     var $keysize;
  90.  
  91.     /**
  92.     * mangled key
  93.     * @var string
  94.     */        
  95.     var $keyhash;
  96.  
  97.     /**
  98.     * source type of the initialization vector for creation  
  99.     * possible types are MCRYPT_RAND or MCRYPT_DEV_URANDOM or MCRYPT_DEV_RANDOM    
  100.     * @var int
  101.     */            
  102.     var $rand_source    = MCRYPT_RAND;
  103.  
  104.     /**
  105.     * header
  106.     * @var string
  107.     */           
  108.     var $header_spec    = 'RandomIV';
  109.  
  110.     /**
  111.     * debugging
  112.     * @var string
  113.     */           
  114.     var $_last_clear;
  115.  
  116.     /**
  117.     * debugging
  118.     * @var string
  119.     */              
  120.     var $_last_crypt;
  121.  
  122.     /**
  123.     * Constructor
  124.     * $key is the key to use for encryption. $cipher can be DES, BLOWFISH or
  125.     * BLOWFISH-COMPAT
  126.     *
  127.     * @param    $key        encryption key
  128.     * @param    $cipher     which algorithm to use, defaults to DES
  129.     *
  130.     * @return   $return     either a PEAR error or true
  131.     *
  132.     * @access   public
  133.     *
  134.     */
  135.  
  136.     function Crypt_CBC ($key, $cipher='DES')
  137.     {
  138.  
  139.         if (!extension_loaded('mcrypt')) {
  140.             return $this->raiseError('mcrypt module is not compiled into PHP', null, 
  141.                 PEAR_ERROR_DIE, null, 'compile PHP using "--with-mcrypt"' );
  142.         }
  143.         if (!function_exists('mcrypt_module_open')) {
  144.             return $this->raiseError('libmcrypt version insufficient', null, 
  145.                 PEAR_ERROR_DIE, null, 'this class requires libmcrypt >= 2.4.x, preferably >= 2.5.5' );
  146.         }
  147.         if (function_exists('mcrypt_generic_deinit')) {
  148.             $this->deinit_function = 'mcrypt_generic_deinit';
  149.         } else if (function_exists('mcrypt_generic_end')) {
  150.             $this->deinit_function = 'mcrypt_generic_end';
  151.         } else {
  152.             return $this->raiseError('PHP version insufficient', null, 
  153.                 PEAR_ERROR_DIE, null, 'this class requires PHP >= 4.0.2, preferably >= 4.1.1' );
  154.         }
  155.  
  156.  
  157.         /* seed randomizer */
  158.  
  159.         srand ((double)microtime()*1000000);
  160.  
  161.         /* initialize */
  162.  
  163.         $this->header_spec = 'RandomIV';
  164.  
  165.         /* check for key */
  166.  
  167.         if (!$key) {
  168.             return $this->raiseError('no key specified');
  169.         }
  170.  
  171.         /* check for cipher */
  172.  
  173.         $cipher = strtoupper($cipher);
  174.         if (!isset($this->known_ciphers[$cipher])) {
  175.             return $this->raiseError('unknown cipher "'.$cipher.'"' );
  176.         }
  177.  
  178.         $this->cipher = $this->known_ciphers[$cipher];
  179.  
  180.         /* initialize cipher */
  181.  
  182.         $this->TD = mcrypt_module_open ($this->cipher, '', 'ecb', '');
  183.         $this->blocksize = mcrypt_enc_get_block_size($this->TD);
  184.         $this->keysize = mcrypt_enc_get_key_size($this->TD);
  185.  
  186.         /* mangle key with MD5 */
  187.  
  188.         $this->keyhash = $this->_md5perl($key);
  189.         while( strlen($this->keyhash) < $this->keysize ) {
  190.             $this->keyhash .= $this->_md5perl($this->keyhash);
  191.         }
  192.  
  193.         $this->key = substr($this->keyhash, 0, $this->keysize);
  194.  
  195.         return true;
  196.  
  197.     }
  198.  
  199.  
  200.     /**
  201.     * Destructor
  202.     *
  203.     */
  204.  
  205.     function _Crypt_CBC ()
  206.     {
  207.         @mcrypt_module_close($this->TD);
  208.     }
  209.  
  210.  
  211.     /**
  212.     * Encryption method
  213.     *
  214.     * @param    $clear      plaintext
  215.     *
  216.     * @return   $crypt      encrypted text, or PEAR error
  217.     *
  218.     * @access   public
  219.     *
  220.     */
  221.  
  222.     function encrypt($clear)
  223.     {
  224.  
  225.         $this->last_clear = $clear;
  226.  
  227.         /* new IV for each message */
  228.  
  229.         $iv = mcrypt_create_iv($this->blocksize, $this->rand_source);
  230.  
  231.         /* create the message header */
  232.  
  233.         $crypt = $this->header_spec . $iv;
  234.  
  235.         /* pad the cleartext */
  236.  
  237.         $padsize = $this->blocksize - (strlen($clear) % $this->blocksize);
  238.         $clear .= str_repeat(pack ('C*', $padsize), $padsize);
  239.  
  240.  
  241.         /* do the encryption */
  242.  
  243.         $start = 0;
  244.         while ( $block = substr($clear, $start, $this->blocksize) ) {
  245.             $start += $this->blocksize;
  246.             if (mcrypt_generic_init($this->TD, $this->key, $iv) < 0 ) {
  247.                 return $this->raiseError('mcrypt_generic_init failed' );
  248.             }
  249.             $cblock = mcrypt_generic($this->TD, $iv^$block );
  250.             $iv = $cblock;
  251.             $crypt .= $cblock;
  252.             call_user_func($this->deinit_function, $this->TD);
  253.         }
  254.  
  255.         $this->last_crypt = $crypt;
  256.         return $crypt;
  257.  
  258.     }
  259.  
  260.  
  261.  
  262.     /**
  263.     * Decryption method
  264.     *
  265.     * @param    $crypt      encrypted text
  266.     *
  267.     * @return   $clear      plaintext, or PEAR error
  268.     *
  269.     * @access   public
  270.     *
  271.     */
  272.  
  273.     function decrypt($crypt) {
  274.  
  275.         $this->last_crypt = $crypt;
  276.  
  277.         /* get the IV from the message header */
  278.  
  279.         $iv_offset = strlen($this->header_spec);
  280.         $header = substr($crypt, 0, $iv_offset);
  281.         $iv = substr ($crypt, $iv_offset, $this->blocksize);
  282.         if ( $header != $this->header_spec ) {
  283.             return $this->raiseError('no initialization vector');
  284.         }
  285.  
  286.         $crypt = substr($crypt, $iv_offset+$this->blocksize);
  287.  
  288.         /* decrypt the message */
  289.  
  290.         $start = 0;
  291.         $clear = '';
  292.  
  293.         while ( $cblock = substr($crypt, $start, $this->blocksize) ) {
  294.             $start += $this->blocksize;
  295.             if (mcrypt_generic_init($this->TD, $this->key, $iv) < 0 ) {
  296.                 return $this->raiseError('mcrypt_generic_init failed' );
  297.             }
  298.             $block = $iv ^ mdecrypt_generic($this->TD, $cblock);
  299.             $iv = $cblock;
  300.             $clear .= $block;
  301.             call_user_func($this->deinit_function, $this->TD);
  302.         }
  303.  
  304.         /* remove the padding from the end of the cleartext */
  305.  
  306.         $padsize = ord(substr($clear, -1));
  307.         $clear = substr($clear, 0, -$padsize);
  308.  
  309.         $this->last_clear = $clear;
  310.         return $clear;
  311.  
  312.     }
  313.  
  314.  
  315.  
  316.     /**
  317.     * Emulate Perl's MD5 function, which returns binary data
  318.     *
  319.     * @param    $string     string to MD5
  320.     *
  321.     * @return   $hash       binary hash
  322.     *
  323.     * @access private
  324.     *
  325.     */
  326.  
  327.     function _md5perl($string)
  328.     {
  329.         return pack('H*', md5($string));
  330.     }
  331. }
  332. ?>
  333.